package nl.tudelft.jpacman.level;

import nl.tudelft.jpacman.npc.Ghost;
import nl.tudelft.jpacman.points.PointCalculator;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;

class PlayerCollisionsTest {
    private PlayerCollisions playerCollisions;
    private PointCalculator pointCalculator;
    @BeforeEach
    void setup(){
        pointCalculator = mock(PointCalculator.class);
        playerCollisions = new PlayerCollisions(pointCalculator);
    }

    @Test
    @Order(1)
    @DisplayName("Player移动到Ghost位置")
    void  playerCollideOnGhost(){
        Player player = mock(Player.class);
        Ghost ghost = mock(Ghost.class);

        playerCollisions.collide(player,ghost);

        verify(pointCalculator).collidedWithAGhost(player,ghost);
        verify(player).setAlive(false);
        verify(player).setKiller(ghost);
    }

    @Test
    @Order(2)
    @DisplayName("Player移动到Pellet位置")
    void  playerCollideOnPellet(){
        Player player = mock(Player.class);
        Pellet pellet = mock(Pellet.class);

        playerCollisions.collide(player,pellet);

        verify(pellet).leaveSquare();
        verify(pointCalculator).consumedAPellet(player,pellet);
    }

    @Test
    @Order(3)
    @DisplayName("Player移动到Player位置")
    void  playerCollideOnPlayer(){
        Player player1 = mock(Player.class);
        Player player2 = mock(Player.class);

        playerCollisions.collide(player1,player2);

        verifyNoMoreInteractions(player1,player2);
    }

    @Test
    @Order(4)
    @DisplayName("Ghost移动到Ghost位置")
    void  ghostCollideOnGhost(){
        Ghost ghost1 = mock(Ghost.class);
        Ghost ghost2 = mock(Ghost.class);

        playerCollisions.collide(ghost1,ghost2);

        verifyNoMoreInteractions(ghost1,ghost2);
    }

    @Test
    @Order(5)
    @DisplayName("Ghost移动到Pellet位置")
    void  ghostCollideOnPellet(){
        Ghost ghost = mock(Ghost.class);
        Pellet pellet = mock(Pellet.class);

        playerCollisions.collide(ghost,pellet);

        verifyNoMoreInteractions(ghost,pellet);
    }

    @Test
    @Order(6)
    @DisplayName("Ghost移动到Player位置")
    void  ghostCollideOnPlayer(){
        Ghost ghost = mock(Ghost.class);
        Player player = mock(Player.class);

        playerCollisions.collide(ghost,player);

        verify(pointCalculator).collidedWithAGhost(player,ghost);
        verify(player).setAlive(false);
        verify(player).setKiller(ghost);
    }

    @Test
    @Order(7)
    @DisplayName("Pellet移动到Ghost位置")
    void  pelletCollideOnGhost(){
        Pellet pellet = mock(Pellet.class);
        Ghost ghost = mock(Ghost.class);

        playerCollisions.collide(pellet,ghost);

        verifyNoMoreInteractions(pellet,ghost);
    }

    @Test
    @Order(8)
    @DisplayName("Pellet移动到Pellet位置")
    void  pelletCollideOnPellet(){
        Pellet pellet1 = mock(Pellet.class);
        Pellet pellet2 = mock(Pellet.class);

        playerCollisions.collide(pellet1,pellet2);

        verifyNoMoreInteractions(pellet1,pellet2);
    }

    @Test
    @Order(9)
    @DisplayName("Pellet移动到Player位置")
    void  pelletCollideOnPlayer(){
        Pellet pellet = mock(Pellet.class);
        Player player = mock(Player.class);

        playerCollisions.collide(pellet,player);

        verify(pellet).leaveSquare();
        verify(pointCalculator).consumedAPellet(player,pellet);
    }

}
